package cn.zhuzicc.basic.jvm.t2;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaoxiang
 * @version 1.0
 * @description 垃圾分代回收示例
 * <p>
 * -Xms20M  初始堆空间
 * -Xmx20M  最大堆空间
 * -Xmn10M  新生代空间
 * -XX:+UseSerialGC 垃圾回收器，jdk1.8默认回收器不是UseSerialGC，需要手动设置下
 * -XX:+PrintGCDetails -verbose:gc  打印GC详情
 * @Date 2021/9/20 21:45
 */
public class Demo1_1 {
    private static final int _512KB = 512 * 1024;
    private static final int _1MB = 1024 * 1024;
    private static final int _6MB = 1024 * 1024 * 6;
    private static final int _7MB = 1024 * 1024 * 7;
    private static final int _8MB = 1024 * 1024 * 8;
    private static final int _10MB = 1024 * 1024 * 10;

    public static void main(String[] args) throws InterruptedException {
        test1();
//        test2();
//        test3();
//        test4();
//        test5();

        // test6()
       /* Thread thread = test6();
        thread.start();
        thread.join();
        System.out.println("sleep.....");
        Thread.sleep(5000L);*/
    }

    /**
     * eden内存不够，触发垃圾回收，存活对象向from中转移
     */
    public static void test1() {
        List<byte[]> list = new ArrayList<>();
        list.add(new byte[_7MB]);
    }

    /**
     * eden内存不够，触发垃圾回收，存活对象向from中转移
     */
    public static void test2() {
        List<byte[]> list = new ArrayList<>();
        list.add(new byte[_7MB]);
        list.add(new byte[_512KB]);
    }

    /**
     * 1.eden内存不够，触发第一次MinorGC回收，将标记对象移至幸存区from内存；
     * 2.from内存不够，触发第二次MinorGC回收，将存活对象晋升到老年代内存；
     */
    public static void test3() {
        List<byte[]> list = new ArrayList<>();
        list.add(new byte[_7MB]);
        list.add(new byte[_512KB]);
        list.add(new byte[_512KB]);
    }

    /**
     * 大对象存储：存储对象总内存大于eden区总内存，则该对象会被直接存储到老年中
     */
    public static void test4() {
        List<byte[]> list = new ArrayList<>();
        list.add(new byte[_8MB]);
    }

    /**
     * 大对象存储：存储对象总内存大于eden区总内存，且老年中也无法容纳下该对象，会直接抛出内存溢出异常
     */
    public static void test5() {
        List<byte[]> list = new ArrayList<>();
        list.add(new byte[_10MB]);
    }

    /**
     * 子线程内存溢出，不会影响主内存的运行
     */
    public static Thread test6() {
        return new Thread(() -> {
            List<byte[]> list = new ArrayList<>();
            list.add(new byte[_8MB]);
            list.add(new byte[_8MB]);
        });
    }
}
